﻿
//////////////////////////////////////////////////////////////////////////////
//
// Copyright © 1998-2024 Glodon Company Limited.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the “Software”),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//////////////////////////////////////////////////////////////////////////////

#include "ObjectBrowserWidget.h"

#include <QPushButton>
#include <QHBoxLayout>
#include <QApplication>
#include <QtGui/qevent.h>
#include "PropertyInstanceWidget.h"
#include "PropertyInstanceSetting.h"
#include "EnableCompileWarning_The_LAST_IncludeInCpp.h"

/// 本文件是界面实现的辅助类，不包含GDMP API的演示内容

using namespace Sample;

namespace Sample
{
    CObjectBrowserWidget::CObjectBrowserWidget(QWidget* pParent /*= NULL*/)
        : QFrame(pParent)
        , m_upApplyButton(nullptr)
        , m_upInstaceWidget(nullptr)
        , m_isHotKeyPressed(false)
    {
        if (pParent)
        {
            resize(pParent->size());
        }

        int defWidth = 268;
        int minWidth = 100;
        int minDefHeight = 250;
        if (width() < defWidth || height() < minDefHeight)
        {
            resize(defWidth, minDefHeight);
            setMinimumSize(minWidth, minDefHeight);
        }

        ////防止全局Style影响
        //setStyle(QStyleFactory::create("WindowsVista"));

        //关闭后清空内存
        setAttribute(Qt::WA_DeleteOnClose, true);

        InitWidget();
    }

    CObjectBrowserWidget::~CObjectBrowserWidget()
    {
    }

    void CObjectBrowserWidget::OnPropertyValueChanged(int groupIndex, int propertyIndex)
    {
        //当属性值发生改变时发出信号
        m_upApplyButton->setEnabled(true);

        // 如果用户按下快捷键，直接应用修改，防止事务不提交
        if (m_isHotKeyPressed)
        {
            m_isHotKeyPressed = false;
            OnApply();
        }
    }

    void CObjectBrowserWidget::OnApply()
    {
        if (m_upApplyButton->isEnabled())
        {
            m_upApplyButton->setEnabled(false);
        }
    }

    bool CObjectBrowserWidget::IsPropertyValueChanged()const
    {
        return m_upApplyButton->isEnabled();
    }

    void CObjectBrowserWidget::InitWidget()
    {
        m_upMainLayout = std::unique_ptr<QVBoxLayout>(new QVBoxLayout(this));
        m_upMainLayout->setContentsMargins(0, 0, 0, 0);
        m_upMainLayout->setSpacing(2);
        //setStyleSheet("PropertyWidget--CPropertyWidget{background-color: rgb(235,235,235)}");

        InitInstanceWidget();
        InitApplyButton();
    }

    void CObjectBrowserWidget::InitInstanceWidget()
    {
        int heightIns = height(); // 这里上面可以加个类名的widget
        m_upInstaceWidget = std::unique_ptr<CInstancePropertyWidget>(new CInstancePropertyWidget(width(), heightIns, new CPropertyInstanceSetting(), this));
        m_upInstaceWidget->setObjectName("ObjectBrowser_Frame");
        m_upInstaceWidget->SetTreePropertyBrowserName("ObjectBrowser");
        connect(m_upInstaceWidget.get(), SIGNAL(FinishedEditing()), this, SLOT(OnApply()));
        connect(m_upInstaceWidget.get(), SIGNAL(PropertyChanged(int, int)), this, SLOT(OnPropertyValueChanged(int, int)));
        connect(this, SIGNAL(mouseLeave()), m_upInstaceWidget.get(), SLOT(OnMouseLeave()));
        connect(m_upInstaceWidget.get(), SIGNAL(sigPropertyBindButtonClicked(int)), this, SIGNAL(sigPropertyBindButtonClicked(int)), Qt::UniqueConnection);
        connect(m_upInstaceWidget.get(), SIGNAL(sigPropertyEditButtonClicked(int)), this, SIGNAL(sigPropertyEditButtonClicked(int)), Qt::UniqueConnection);
        connect(m_upInstaceWidget.get(), SIGNAL(DropDownListIndexChange(int, int)), this, SIGNAL(DropDownListIndexChange(int, int)), Qt::UniqueConnection);
        connect(m_upInstaceWidget.get(), SIGNAL(sigHidePopup(QObject*)), this, SLOT(OnCheckLeaveEvent(QObject*)), Qt::UniqueConnection);

        m_upInstaceWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
        m_upInstaceWidget->installEventFilter(this);
        m_upMainLayout->addWidget(m_upInstaceWidget.get());
    }

    void CObjectBrowserWidget::InitApplyButton()
    {
        m_upApplyButton = std::unique_ptr<QPushButton>(new QPushButton(QStringLiteral("Apply"), this));
        m_upApplyButton->setObjectName(QString("PropertyWidgetApplyButton"));//Add by gaoyu
        m_upApplyButton->setMaximumWidth(90);
        m_upApplyButton->setMinimumWidth(70);
        m_upApplyButton->setFixedHeight(22);
        m_upApplyButton->resize(90, 22);
        m_upApplyButton->setEnabled(false);
        connect(m_upApplyButton.get(), SIGNAL(clicked(bool)), this, SLOT(OnApply()));

        //应用按钮布局
        m_upButtonLayout = std::unique_ptr<QHBoxLayout>(new QHBoxLayout(this));
        m_upButtonLayout->setContentsMargins(0, 8, 0, 0);
        m_upButtonLayout->addStretch(0);
        m_upButtonLayout->addWidget(m_upApplyButton.get(), 1, Qt::AlignVCenter);
        m_upMainLayout->addLayout(m_upButtonLayout.get());
    }

    bool CObjectBrowserWidget::IsAlphaKeys(int nChar)
    {
        if (nChar >= 0x41 && nChar <= 0x5a) // 大键盘的字符键
        {
            return true;
        }
        return false;
    }

    void CObjectBrowserWidget::setApplyButtonText(const QString& text)
    {
        if (m_upApplyButton)
        {
            m_upApplyButton->setText(text);
        }
    }

    bool CObjectBrowserWidget::eventFilter(QObject *object, QEvent *event)
    {
        if (event->type() == QEvent::FocusOut) {
            QFocusEvent *fe = static_cast<QFocusEvent *>(event);
            if (fe->reason() == Qt::ActiveWindowFocusReason)
                return false;
        }
        return QFrame::eventFilter(object, event);
    }

    void CObjectBrowserWidget::keyPressEvent(QKeyEvent *event)
    {
        //过滤子窗口连续按下的Ctrl,Atl,Shift等键，不再继续消息链
        //注意：此处修改目的是（防止日志勿记录，shift键转发到View会和鼠标事件会被日志勿记录为操作视图）
        int key = event->key();
        if (key == Qt::Key_Control || key == Qt::Key_Shift ||
            key == Qt::Key_Meta || key == Qt::Key_Alt ||
            key == Qt::Key_Super_L || key == Qt::Key_AltGr)
            return;

        // 按键为字母，意味着用户正在使用快捷键执行其他命令
        if (IsAlphaKeys(key))
        {
            m_isHotKeyPressed = true;
        }

        switch (event->key())
        {
        case Qt::Key_Return: //大键盘Enter键
        case Qt::Key_Enter: //小键盘Enter键
            OnApply();
            event->accept();
            return;  //返回不在进入消息链
        default:
            break;
        }

        QFrame::keyPressEvent(event);
    }

    void CObjectBrowserWidget::leaveEvent(QEvent *event)
    {
        //注意：判断鼠标范围是否在属性面板区域，排除因为ComboBox激活带来的leaveEvent
        // widget coordinate
        QRect rect(0, 0, this->width(), this->height());
        // the global screen coordinate pos to widget coordinates.
        QPoint cursorPoint = this->mapFromGlobal(QCursor::pos());
        if (rect.contains(cursorPoint))
            return;

        emit mouseLeave();
        OnApply();
    }

    void CObjectBrowserWidget::OnCheckLeaveEvent(QObject* obj) {

    }
}

